'----------------------------------------------
' Name: Brian Culp
'       Chris Hanegraaf
'       Ali Karbassi
'       Matt Latzke
' Date: April 26, 2007
' Description: Project 7
'              Enum UserState
'              Class UserAccount
'----------------------------------------------
Imports System.Threading

Public Enum UserState
   Started
   Working
   Waiting
   Terminating
   Terminated
End Enum

Public Delegate Sub Transaction(ByVal ID As String, ByVal value As Integer, ByVal Final As Boolean)
Public Delegate Sub PassMsg(ByVal myID As String, ByVal theState As UserState)

Public Class UserAccount

   Public mainForm As Form
   Public DoTransaction As Transaction
   Public Report As PassMsg

   Private userThread As Thread
   Private Paused As New AutoResetEvent(False)
   Private _userState As UserState
   Private subTotal As Short = 0

   ''' <summary>
   ''' Returns the GetHashCode value of the user thread. 
   ''' You must put two-characters initials of one student in front of the ID.
   ''' </summary>
   ''' <value></value>
   ''' <returns></returns>
   ''' <remarks></remarks>
   Public ReadOnly Property ID() As String
      Get
         Return "AK" & userThread.GetHashCode
      End Get
   End Property

   Public ReadOnly Property State() As UserState
      Get
         Return _userState
      End Get
   End Property

   Public Sub SpinUp()

      userThread = New Thread(AddressOf Run)
      _userState = UserState.Started
      userThread.Start()

   End Sub

   Public Sub SpinDown()

      If _userState = UserState.Waiting Then
         UserContinue()
      End If

      _userState = UserState.Terminating
      userThread.Join(5000)

   End Sub

   Public Sub UserStop()

      _userState = UserState.Waiting
   End Sub

   Public Sub UserContinue()
      _userState = UserState.Working
      Paused.Set()
   End Sub

   Private Sub Run()

      'Report user state
      _userState = UserState.Started
      mainForm.Invoke(Report, ID, _userState)

      'Set seed for myGenerator
      Dim myGenerator As New Random((Now().Millisecond))

      _userState = UserState.Working

      While True

         If _userState = UserState.Waiting Then

            'Report user state
            mainForm.Invoke(Report, ID, _userState)

            'Wait until being resumed or terminated
            Paused.WaitOne()

         End If

         If _userState = UserState.Terminating Then
            'Report user state
            mainForm.Invoke(Report, ID, _userState)

            'Exit loop
            Exit While
         End If

         'Report user state
         mainForm.Invoke(Report, ID, _userState)

         'Go to work for some time 
         Thread.Sleep(myGenerator.Next(3000, 5000))

         'Generate a transaction amount
         Dim value As Integer = myGenerator.Next(-100, 100)

         'Issue a transaction of the amount
         mainForm.Invoke(DoTransaction, ID, value, False)

         subTotal += value

      End While

      _userState = UserState.Terminated
      mainForm.Invoke(DoTransaction, ID, subTotal, True)
      mainForm.Invoke(Report, ID, _userState)

   End Sub
End Class
